﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace aaaSoft.SkinEngine.SkinHelpers
{
    static class ColorHelper
    {
        #region 获取比指定颜色更深(浅)的颜色
        /// <summary>
        /// 获取比指定颜色更深(浅)的颜色
        /// </summary>
        /// <param name="srcColor">原颜色</param>
        /// <param name="deep">深度(1为原色，大于1变浅，小于1变深)</param>
        /// <returns></returns>
        public static Color GetDeeperColor(Color srcColor, float deep)
        {
            int H, S, B;
            RGB2HSB(srcColor, out H, out S, out B);
            return HSB2RGBColor(H, S, (int)(B * deep));
        }
        #endregion

        #region 获取原颜色相反的颜色
        /// <summary>
        /// 获取原颜色相反的颜色
        /// </summary>
        /// <param name="srcColor"></param>
        /// <returns></returns>
        public static Color GetDLColor(Color srcColor)
        {
            return ColorHelper.GetDeeperColor(Color.FromArgb(255 - srcColor.R, 255 - srcColor.G, 255 - srcColor.B), 2.0f);
        }
        #endregion

        #region HSB与RGB颜色互转函数
        public static Color HSB2RGBColor(int hue, int sat, int bri)
        {
            int r, g, b;
            //begin:HSB转换为float 
            if (hue > 239)
            {
                hue = 239;
            }
            else
            {
                if (hue < 0)
                {
                    hue = 0;
                }
            }

            if (sat > 240)
            {
                sat = 240;
            }
            else
            {
                if (sat < 0)
                {
                    sat = 0;
                }
            }

            if (bri > 240)
            {
                bri = 240;
            }
            else
            {
                if (bri < 0)
                {
                    bri = 0;
                }
            }

            float H = hue / 239.0f;
            float S = sat / 240.0f;
            float L = bri / 240.0f;

            float red = 0, green = 0, blue = 0;
            float d1, d2;

            if (L == 0)
            {
                red = green = blue = 0;
            }
            else
            {
                if (S == 0)
                {
                    red = green = blue = L;
                }
                else
                {
                    d2 = (L <= 0.5f) ? L * (1.0f + S) : L + S - (L * S);
                    d1 = 2.0f * L - d2;

                    float[] d3 = new float[] { H + 1.0f / 3.0f, H, H - 1.0f / 3.0f };
                    float[] rgb = new float[] { 0, 0, 0 };

                    for (int i = 0; i < 3; i++)
                    {
                        if (d3[i] < 0)
                        {
                            d3[i] += 1.0f;
                        }

                        if (d3[i] > 1.0f)
                        {
                            d3[i] -= 1.0f;
                        }

                        if (6.0f * d3[i] < 1.0f)
                        {
                            rgb[i] = d1 + (d2 - d1) * d3[i] * 6.0f;
                        }
                        else
                        {
                            if (2.0f * d3[i] < 1.0f)
                            {
                                rgb[i] = d2;
                            }
                            else
                            {
                                if (3.0f * d3[i] < 2.0f)
                                {
                                    rgb[i] = (d1 + (d2 - d1) * ((2.0f / 3.0f) - d3[i]) * 6.0f);
                                }
                                else
                                {
                                    rgb[i] = d1;
                                }
                            }
                        }
                    }

                    red = rgb[0];
                    green = rgb[1];
                    blue = rgb[2];
                }
            }

            red = 255.0f * red;
            green = 255.0f * green;
            blue = 255.0f * blue;

            if (red < 1)
            {
                red = 0.0f;
            }
            else
            {
                if (red > 255.0f)
                {
                    red = 255.0f;
                }
            }

            if (green < 1)
            {
                green = 0.0f;
            }
            else
            {
                if (green > 255.0f)
                {
                    green = 255.0f;
                }
            }

            if (blue < 1)
            {
                blue = 0.0f;
            }
            else
            {
                if (blue > 255.0f)
                {
                    blue = 255.0f;
                }
            }

            r = (int)(red + 0.5);
            g = (int)(green + 0.5);
            b = (int)(blue + 0.5);
            return Color.FromArgb(r, g, b);
        }
        public static void RGB2HSB(Color cor, out int hue, out int sat, out int bri)
        {
            RGB2HSB(cor.R, cor.G, cor.B, out hue, out sat, out bri);
        }
        public static void RGB2HSB(int r, int g, int b, out float hue, out float sat, out float bri)
        {
            int minval = Math.Min(r, Math.Min(g, b));
            int maxval = Math.Max(r, Math.Max(g, b));

            //bri 
            bri = (float)(maxval + minval) / 510;

            //sat 
            if (maxval == minval)
            {
                sat = 0.0f;
            }
            else
            {
                int sum = maxval + minval;

                if (sum > 255)
                {
                    sum = 510 - sum;
                }

                sat = (float)(maxval - minval) / sum;
            }

            //hue 
            if (maxval == minval)
            {
                hue = 0.0f;
            }
            else
            {
                float diff = (float)(maxval - minval);
                float rnorm = (maxval - r) / diff;
                float gnorm = (maxval - g) / diff;
                float bnorm = (maxval - b) / diff;

                hue = 0.0f;

                if (r == maxval)
                {
                    hue = 60.0f * (6.0f + bnorm - gnorm);
                }

                if (g == maxval)
                {
                    hue = 60.0f * (2.0f + rnorm - bnorm);
                }

                if (b == maxval)
                {
                    hue = 60.0f * (4.0f + gnorm - rnorm);
                }

                if (hue > 360.0f)
                {
                    hue = hue - 360.0f;
                }
            }
        }
        public static void RGB2HSB(int r, int g, int b, out int hue, out int sat, out int bri)
        {
            float fHue, fSat, fBri;

            RGB2HSB(r, g, b, out fHue, out fSat, out fBri);

            hue = (int)((fHue / 360.0f) * 240 + 0.5);
            sat = (int)(fSat * 241 + 0.5);
            bri = (int)(fBri * 241 + 0.5);

            if (hue > 239)
            {
                hue = 239;
            }

            if (sat > 240)
            {
                sat = 240;
            }

            if (bri > 240)
            {
                bri = 240;
            }
        }
        #endregion

        #region 改变黑白图片为指定颜色的图片
        /// <summary>
        /// 改变黑白图片为指定颜色的图片
        /// </summary>
        /// <param name="srcBmp">原黑白图片</param>
        /// <param name="desColor">要改变为的颜色</param>
        /// <returns></returns>
        public static Bitmap ChangeImageToColorImage(Bitmap srcBmp, Color desColor)
        {
            return ChangeImageToColorImage(srcBmp, desColor, 50);
        }
        public static Bitmap ChangeImageToColorImage(Bitmap srcBmp, Color desColor, Int32 addLight)
        {
            //return srcBmp;
            Bitmap back = new Bitmap(srcBmp);
            for (int i = 0; i <= back.Height - 1; i++)
            {
                for (int j = 0; j <= back.Width - 1; j++)
                {
                    Color tmpColor;
                    tmpColor = back.GetPixel(j, i);
                    Int32 R, G, B;
                    R = Convert.ToInt32(desColor.R) * Convert.ToInt32(tmpColor.B) / (128 + addLight);
                    G = Convert.ToInt32(desColor.G) * Convert.ToInt32(tmpColor.B) / (128 + addLight);
                    B = Convert.ToInt32(desColor.B) * Convert.ToInt32(tmpColor.B) / (128 + addLight);
                    if (R > 255) R = 255;
                    if (G > 255) G = 255;
                    if (B > 255) B = 255;
                    tmpColor = Color.FromArgb(tmpColor.A, R, G, B);
                    back.SetPixel(j, i, tmpColor);
                }
            }
            return back;
        }
        #endregion

        #region 获取随机颜色
        /// <summary>
        /// 获取随机颜色
        /// </summary>
        /// <returns></returns>
        public static Color GetRandomColor()
        {
            Random rnd = new Random();
            int R, G, B;
            R = rnd.Next(0, 255);
            G = rnd.Next(0, 255);
            B = rnd.Next(0, 255);
            return Color.FromArgb(R, G, B);
        }
        #endregion
    }
}
